package com.demo2do.fms.admin.service.report.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.entity.page.Page;
import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.persistence.support.QueryFilter;
import com.demo2do.fms.admin.entity.export.report.TransportToolSheet;
import com.demo2do.fms.admin.entity.report.report.BusinessHistoryReportSearch;
import com.demo2do.fms.admin.entity.report.report.ParkingResourceReportSearch;
import com.demo2do.fms.admin.entity.report.report.StaffReportSearch;
import com.demo2do.fms.admin.entity.search.report.TransportToolSearch;
import com.demo2do.fms.admin.handler.support.FmsJdbcSupport;
import com.demo2do.fms.admin.service.report.SupplierReportService;
import com.demo2do.fms.entity.supplier.common.Supplier;
import com.demo2do.fms.entity.vehicle.source.VehicleSource;
import com.demo2do.fms.entity.vehicle.tractor.Tractor;
import com.demo2do.fms.entity.vehicle.trailer.Trailer;

/**
 *
 * @author Ark
 *
 */
@Service("SupplierReportService")
public class SupplierReportServiceImpl implements SupplierReportService {

    @Autowired
    private FmsJdbcSupport fmsJdbcSupport;
    
    @Autowired
    private GenericDaoSupport genericDaoSupport;
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#count(com.demo2do.fms.admin.entity.report.report.BusinessHistoryReportSearch)
     */
    public int count(BusinessHistoryReportSearch search) {
        String sentence = search.buildCountTemplate();
        Map<String, Object> parameters = search.buildParameters();
        return fmsJdbcSupport.queryForInt(sentence, parameters);
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#search(com.demo2do.fms.admin.entity.report.report.BusinessHistoryReportSearch, com.demo2do.core.entity.page.Page)
     */
    public List<Map<String, Object>> search(BusinessHistoryReportSearch search, Page page) {
        
        // 1. calculate page
        Integer beginIndex = page.getBeginIndex() + 1;
        search.setBeginIndex(beginIndex);
        
        Integer endIndex = page.getCurrentPage() * page.getEveryPage();
        search.setEndIndex(endIndex);
        
        // 2. build parameters
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        
        // 3. do query
        List<Map<String, Object>> result = fmsJdbcSupport.queryForList(sentence, parameters, search.buildRowMapper());
        page.calculate();
        return result;
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#count(com.demo2do.fms.admin.entity.report.report.ParkingResourceReportSearch)
     */
    public int count(ParkingResourceReportSearch search) {
        String sentence = search.buildCountTemplate();
        Map<String, Object> parameters = search.buildParameters();
        return fmsJdbcSupport.queryForInt(sentence, parameters);
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#search(com.demo2do.fms.admin.entity.report.report.ParkingResourceReportSearch, com.demo2do.core.entity.page.Page)
     */
    public List<Map<String, Object>> search(ParkingResourceReportSearch search, Page page) {
     
        // 1. calculate page
        Integer beginIndex = page.getBeginIndex() + 1;
        search.setBeginIndex(beginIndex);
        
        Integer endIndex = page.getCurrentPage() * page.getEveryPage();
        search.setEndIndex(endIndex);
        
        // 2. build parameters
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        
        // 3. do query
        List<Map<String, Object>> result = fmsJdbcSupport.queryForList(sentence, parameters, search.buildRowMapper());
        page.calculate();
        return result;
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#count(com.demo2do.fms.admin.entity.report.report.StaffReportSearch)
     */
    public int count(StaffReportSearch search) {
        String sentence = search.buildCountTemplate();
        Map<String, Object> parameters = search.buildParameters();
        return fmsJdbcSupport.queryForInt(sentence, parameters);
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#search(com.demo2do.fms.admin.entity.report.report.StaffReportSearch, com.demo2do.core.entity.page.Page)
     */
    public List<Map<String, Object>> search(StaffReportSearch search, Page page) {
        
        // 1. calculate page
        Integer beginIndex = page.getBeginIndex() + 1;
        search.setBeginIndex(beginIndex);
        
        Integer endIndex = page.getCurrentPage() * page.getEveryPage();
        search.setEndIndex(endIndex);
        
        // 2. build parameters
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        
        // 3. do query
        List<Map<String, Object>> result = fmsJdbcSupport.queryForList(sentence, parameters, search.buildRowMapper());
        page.calculate();
        return result;
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#count(com.demo2do.fms.admin.entity.search.report.TransportToolSearch)
     */
    public int count(TransportToolSearch search) {
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        return genericDaoSupport.count(sentence, parameters);
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#search(com.demo2do.fms.admin.entity.search.report.TransportToolSearch, com.demo2do.core.entity.page.Page)
     */
    @SuppressWarnings("unchecked")
    public List<TransportToolSheet> search(TransportToolSearch search, Page page) {
        
        // 1. build parameters
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        
        // 2. do query
        page.calculate();
        List<Supplier> suppliers = genericDaoSupport.searchForList(sentence, parameters, page.getBeginIndex(), page.getEveryPage());

        // 3. construct suppliers to transportTools
        List<TransportToolSheet> transportToolSheets = this.parseTransportToolSheet(suppliers, search);
        return transportToolSheets;
        
    }
    
    /* (non-Javadoc)
     * @see com.demo2do.fms.admin.service.report.SupplierReportService#export(com.demo2do.fms.admin.entity.search.report.TransportToolSearch)
     */
    @SuppressWarnings("unchecked")
    public List<TransportToolSheet> export(TransportToolSearch search) {
        
        // 1. build parameters
        String sentence = search.buildSentenceTemplate();
        Map<String, Object> parameters = search.buildParameters();
        
        // 2. query and transform to sheet
        List<Supplier> suppliers = genericDaoSupport.searchForList(sentence, parameters);
        List<TransportToolSheet> transportToolSheets = this.parseTransportToolSheet(suppliers, search);
        return transportToolSheets;
        
    }
    
    /**
     * @param suppliers
     * @param search
     * @return
     */
    @SuppressWarnings({ "deprecation" })
    public List<TransportToolSheet> parseTransportToolSheet(List<Supplier> suppliers, TransportToolSearch search) {
        
        List<TransportToolSheet> tools = new ArrayList<TransportToolSheet>();
        
        for (Supplier supplier : suppliers) {
            
            List<VehicleSource> vehicleSources = this.listVehicleSource(supplier.getId(), search);
            
            // 1位车型数量
            int oneLoads = 0;
            // 2位车型数量
            int twoLoads = 0;
            // 6位车型数量
            int sixLoads = 0;
            // 7位车型数量
            int sevenLoads = 0;
            // 8位车型数量
            int eightLoads = 0;
            // 10位车型数量
            int tenLoads = 0;
            // 12位车型数量
            int twelveLoads = 0;
            // 超过14位车型数量
            int fourteenLoads = 0;
            // 其他车型数量
            int otherLoads = 0;
            // 有效运力
            int syncVehicles = 0;
            // 锁定运力
            int lockVehicles = 0;
            // 总运力
            int totalVehicles = vehicleSources.size();
            // 平均装载量
            int avgLoads = 0;
            // 总装载量
            int totalLoads = 0;
            // 总车龄
            int totalVehicleAge = 0;
            // 平均年龄
            int avgVehicleAge = 0;
            
            for (VehicleSource vehicleSource : vehicleSources) {
                
                // 装载量
                int vehicleSourceFullLoad = 0;
                
                if (vehicleSource.getTractorId() != null) {
                    Tractor tractor = genericDaoSupport.load(Tractor.class, vehicleSource.getTractorId());
                    if (tractor.getTrainload() != null) {
                        vehicleSourceFullLoad = vehicleSourceFullLoad + tractor.getTrainload().intValue();
                    }
                    
                    Date registrationTime = tractor.getRegistrationTime();
                    if (registrationTime != null) {
                        int betweenYears = new Date().getYear() - registrationTime.getYear();
                        totalVehicleAge += betweenYears;
                    }
                }
                if (vehicleSource.getTrailerId() != null) {
                    Trailer trailer = genericDaoSupport.load(Trailer.class, vehicleSource.getTrailerId());
                    if (trailer.getTrainload() != null) {
                        vehicleSourceFullLoad = vehicleSourceFullLoad + trailer.getTrainload().intValue();
                    }
                }
                // 处理装载量
                totalLoads = totalLoads + vehicleSourceFullLoad;
                // 处理车型数量
                if (vehicleSourceFullLoad == 1) {
                    oneLoads++;
                } else if (vehicleSourceFullLoad == 2) {
                    twoLoads++;
                } else if (vehicleSourceFullLoad == 6) {
                    sixLoads++;
                } else if (vehicleSourceFullLoad == 7) {
                    sevenLoads++;
                } else if (vehicleSourceFullLoad == 8) {
                    eightLoads++;
                } else if (vehicleSourceFullLoad == 10) {
                    tenLoads++;
                } else if (vehicleSourceFullLoad == 12) {
                    twelveLoads++;
                } else if (vehicleSourceFullLoad >= 14) {
                    fourteenLoads++;
                } else {
                    otherLoads++;
                }
                // 处理有效运力
                if (vehicleSource.getSynchronize()) {
                    syncVehicles++;
                }
                // 处理锁定运力
                if (vehicleSource.isLock()) {
                    lockVehicles++;
                }
            }
            
            avgVehicleAge = totalVehicles != 0 ? (totalVehicleAge / totalVehicles) : 0;
            
            // 处理平均装载量
            avgLoads = totalVehicles != 0 ? (totalLoads / totalVehicles) : 0;
            
            TransportToolSheet tool = new TransportToolSheet(supplier, totalVehicles, oneLoads, twoLoads, sixLoads, sevenLoads, eightLoads, tenLoads, twelveLoads, fourteenLoads, otherLoads, avgLoads, avgVehicleAge, syncVehicles, lockVehicles);
            tools.add(tool);
            
            
            /**
            // 总运力
            List<VehicleSource> sources = this.listVehicleSource(supplier.getId(), search);
            int totalVehicles = sources.size();
            
            List<Long> tractorIds = CollectionUtils.extractPropertyList(sources, "tractorId");
            List<Tractor> tractors = new ArrayList<Tractor>();
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(tractorIds)) {
                for (Long tractorId : tractorIds) {
                    tractors.add(genericDaoSupport.load(Tractor.class, tractorId));
                }
            }
            
            List<Long> trailerIds = CollectionUtils.extractPropertyList(sources, "trailerId");
            List<Trailer> trailers = new ArrayList<Trailer>();
            trailerIds.removeAll(Collections.singleton(null));
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(trailerIds)) {
                for (Long trailerId : trailerIds) {
                    trailers.add(genericDaoSupport.load(Trailer.class, trailerId));
                }
            }
            
            // 平均装载量
            int totalLoads = 0;
            for (Trailer trailer : trailers) {
                if (trailer.getTrainload() != null) {
                    totalLoads += trailer.getTrainload().intValue();
                }
            }
            int avgLoads = totalVehicles != 0 ? (totalLoads / totalVehicles) : 0;
            
            // 1位车型数量
            int oneLoads = 0;
            // 2位车型数量
            int twoLoads = 0;
            // 6位车型数量
            int sixLoads = 0;
            // 7位车型数量
            int sevenLoads = 0;
            // 8位车型数量
            int eightLoads = 0;
            // 10位车型数量
            int tenLoads = 0;
            // 12位车型数量
            int twelveLoads = 0;
            // 超过14位车型数量
            int fourteenLoads = 0;
            // 其他车型数量
            int otherLoads = 0;
            
            for (Trailer trailer : trailers) {
                
                if (trailer.getTrainload() == null) {
                    continue;
                }
                
                int fullLoad = trailer.getTrainload().intValue();
                
                if (fullLoad == 1) {
                    oneLoads++;
                } else if (fullLoad == 2) {
                    twoLoads++;
                } else if (fullLoad == 6) {
                    sixLoads++;
                } else if (fullLoad == 7) {
                    sevenLoads++;
                } else if (fullLoad == 8) {
                    eightLoads++;
                } else if (fullLoad == 10) {
                    tenLoads++;
                } else if (fullLoad == 12) {
                    twelveLoads++;
                } else if (fullLoad >= 14) {
                    fourteenLoads++;
                } else {
                    otherLoads++;
                }
                
            }
            
            // 平均车龄
            int totalVehicleAge = 0;
            for (Tractor tractor : tractors) {
                
                Date registrationTime = tractor.getRegistrationTime();
                if (registrationTime != null) {
                    int betweenYears = LocalDate.now().getYear() - registrationTime.getYear();
                    totalVehicleAge += betweenYears;
                }
                
            }
            int avgVehicleAge = tractors.size() != 0 ? (totalVehicleAge / tractors.size()) : 0;
            
            // 有效运力
            int syncVehicles = 0;
            // 锁定运力
            int lockVehicles = 0;
            
            for (VehicleSource source : sources) {
                
                if (source.getSynchronize()) {
                    syncVehicles++;
                }
                
                if (source.isLock()) {
                    lockVehicles++;
                }
                
            }
            
            TransportToolSheet tool = new TransportToolSheet(supplier, totalVehicles, oneLoads, twoLoads, sixLoads, sevenLoads, eightLoads, tenLoads, twelveLoads, fourteenLoads, otherLoads, avgLoads, avgVehicleAge, syncVehicles, lockVehicles);
            tools.add(tool);
            **/
        }
        
        return tools;
        
    }
    
    /**
     * @param supplierId
     * @param search
     * @return
     */
    @SuppressWarnings("unchecked")
    private List<VehicleSource> listVehicleSource(Long supplierId, TransportToolSearch search) {
        
        QueryFilter queryFilter = new QueryFilter();
        queryFilter.addEquals("supplier", "id", supplierId);
        queryFilter.addEquals("status", search.getStatus());
        queryFilter.addEquals("synchronize", search.getSynchronize());
        
        String sentence = "FROM VehicleSource WHERE disabled = false" + queryFilter.clauseSentence();
        return genericDaoSupport.searchForList(sentence, queryFilter.parameters());
        
    }
    
}
